package com.dili.dd.gpi.service.impl;

import com.dili.dd.gpi.domain.GciSnapshot;
import com.dili.dd.gpi.domain.GciSnapshotExample;
import com.dili.dd.gpi.enums.ApplyType;
import com.dili.dd.gpi.enums.GCIType;
import com.dili.dd.gpi.enums.PrefixType;
import com.dili.dd.gpi.exception.BusinessException;
import com.dili.dd.gpi.mapper.ExtGciSnapshotMapper;
import com.dili.dd.gpi.mapper.GciSnapshotMapper;
import com.dili.dd.gpi.service.GciSnapshotService;
import com.dili.dd.gpi.service.UidNameSpaceService;
import com.dili.dd.gpi.util.Pagination;
import com.dili.dd.gpi.util.StringUtils;
import com.dili.dd.gpi.util.spring.DataSourceLookupKey;
import com.dili.dd.gpi.util.spring.RequireDataSource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * Created by zhaoYuan on 2015/3/24.
 */
@Service
public class GciSnapshotServiceImpl implements GciSnapshotService {


    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Resource
    private GciSnapshotMapper gciSnapshotMapper;

    @Resource
    private UidNameSpaceService uidNameSpaceService;

    @Resource
    private ExtGciSnapshotMapper extGciSnapshotMapper;

    @Override
    @RequireDataSource(key = DataSourceLookupKey.GPI_DATASOURCE)
    @Transactional(readOnly = false,propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public boolean apply(Set<String> titles, GCIType type, String prefix, String suffix, List<String> descriptions,
                         List<GciSnapshot> gciSnapshots, List<GciSnapshot> newGcis, ApplyType applyType) throws BusinessException {
        //先判断title在type下是否已经存在，就抛出异常
        List<String> titleList = new LinkedList<>(titles);
        List<GciSnapshot> exists = isExist(titleList, type);
        Set<String> existTitles = new HashSet<>();
        if (exists != null) {
            for (GciSnapshot gs : exists){
                gciSnapshots.add(gs);
                existTitles.add(gs.getTitle());
            }
            titleList.removeAll(existTitles);
        }

        Date now = new Date();

        //如果不存在，则申请一个gci
        int generateNumber = titleList.size();
        List<String> gcis = generateGCI(PrefixType.GCI, prefix, applyType, suffix, generateNumber,"C-"+type.name());
        if(gcis != null && !gcis.isEmpty()){
            if(gcis.size() != titleList.size()) throw new BusinessException("系统错误，gci数量和title数量不相等");
            for (int i = 0; i < titleList.size(); i++) {
                GciSnapshot gciSnapshot = new GciSnapshot();
                gciSnapshot.setType(type);
                gciSnapshot.setTitle(titleList.get(i));
                gciSnapshot.setSuffix(suffix);
                gciSnapshot.setPrefix(prefix);
                gciSnapshot.setGci(gcis.get(i));
                if(i < descriptions.size()){
                    gciSnapshot.setDescribe(descriptions.get(i));
                }
                gciSnapshot.setUpdateTime(now);
                gciSnapshot.setCreateTime(now);
                gciSnapshot.setDeleted(false);
                gciSnapshotMapper.insert(gciSnapshot);
                newGcis.add(gciSnapshot);
            }
        }
        return true;
    }

    @Override
    @RequireDataSource(key = DataSourceLookupKey.GPI_DATASOURCE)
    @Transactional(readOnly = true,propagation = Propagation.REQUIRED)
    public List<GciSnapshot> find( Map<String, Object> params, Pagination pagination) {
        if(pagination != null){
            params.put("pagination",pagination);
        }
        List<GciSnapshot> gciSnapshots = extGciSnapshotMapper.findByParams(params);
        return gciSnapshots;
    }

    @Override
    @RequireDataSource(key = DataSourceLookupKey.GPI_DATASOURCE)
    @Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
    public List<GciSnapshot> isExist(List<String> titles, GCIType type){
        GciSnapshotExample example = new GciSnapshotExample();
        GciSnapshotExample.Criteria criteria = example.createCriteria();
        criteria.andDeletedEqualTo(false).andTitleIn(titles).andTypeEqualTo(type);
        List<GciSnapshot> gciSnapshots = gciSnapshotMapper.selectByExample(example);
        return gciSnapshots == null || gciSnapshots.isEmpty() ? null : gciSnapshots;
    }

    private List<String> generateGCI(PrefixType type, String prefix, ApplyType applyType, String suffix, int n,String level) throws BusinessException {
        if(n < 1) return null;
        List<String> gcis = new LinkedList<>();
        for (int i = 0; i < n; i++) {
            String gci = uidNameSpaceService.generateUID(PrefixType.GCI, prefix, applyType, level);
            if(!StringUtils.isNullOrEmpty(suffix)){
                gci = gci + suffix;
            }
            gcis.add(gci);
        }
        return gcis;
    }
}
